package com.quick.framework.service;

import com.quick.common.constants.CacheConstants;
import com.quick.common.exception.ServiceException;
import com.quick.common.redis.RedisCache;
import com.quick.common.utils.SecurityUtils;
import com.quick.common.utils.StringUtils;
import com.quick.framework.properties.UserPasswordProperties;
import com.quick.framework.security.context.AuthenticationContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 登录密码方法
 *
 * @Author: Administrator
 * @Date: 2023/7/27
 */
@Component
public class PasswordService {
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private UserPasswordProperties userPasswordProperties;

    /**
     * 登录账户密码错误次数缓存键名
     *
     * @param username 用户名
     * @return 缓存键key
     */
    private String getCacheKey(String username) {
        return CacheConstants.PWD_ERR_CNT_KEY + username;
    }

    public void validate(String userPassword) {
        Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
        String username = usernamePasswordAuthenticationToken.getName();
        String password = usernamePasswordAuthenticationToken.getCredentials().toString();
        Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
        if (retryCount == null) {
            retryCount = 0;
        }
        if (retryCount >= userPasswordProperties.getMaxRetryCount()) {
            throw new ServiceException(StringUtils.format("密码输入错误{}次，帐户锁定{}分钟！", userPasswordProperties.getMaxRetryCount(), userPasswordProperties.getLockTime()));
        }
        if (!SecurityUtils.matchesPassword(password,userPassword)) {
            retryCount = retryCount + 1;
            redisCache.setCacheObject(getCacheKey(username), retryCount, userPasswordProperties.getLockTime(), TimeUnit.MINUTES);
            int surplusCount = userPasswordProperties.getMaxRetryCount() - retryCount;
            if (surplusCount == 0) {
                throw new ServiceException(StringUtils.format("密码输入错误{}次，帐户锁定{}分钟！", retryCount, userPasswordProperties.getLockTime()));
            }
            throw new ServiceException(StringUtils.format("密码输入错误{}次，剩余{}次机会！", retryCount, surplusCount));
        } else {
            clearLoginLockCache(username);
        }
    }

    public void clearLoginLockCache(String loginName) {
        if (redisCache.hasKey(getCacheKey(loginName))) {
            redisCache.deleteObject(getCacheKey(loginName));
        }
    }
}
